/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 *  The greatest achievement is selflessness. The greatest worth is self-mastery.
 *  The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 *  The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 *  The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 *  The greatest goodness is a peaceful mind. The greatest patience is humility.
 *  The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 *  The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 * 
 * @author Ashin Wimalajeewa (ash)
 */
package org.javaongems.gwk.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.javaongems.std.client.Gem;
import org.javaongems.std.client.HistoryUtils;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

public abstract class AbstractPageCoordinator 
	implements PagePanel.Listener, WindowResizeListener, HistoryListener {
	
	private String bootstrapUrl;
	private boolean isUrlBootstrapped = true;
	protected Map/*<Widget,AbstractPageController>*/ pageControllerMap = new HashMap();
	protected Map/*<String,AbstractPageController>*/ pageNameControllerMap = new HashMap();
	protected List/*<AbstractPageController>*/ controllers = new ArrayList();
	
	abstract public Widget getCoordinatedView();
	abstract public PagePanel getPagePanel();
	
	public void setUp(RootPanel mountPoint) {
		bootstrapUrl = HistoryUtils.getHash();
		if (Gem.stone.isDebugEnabled())
			Gem.stone.log(this, "bootstrapHash: " + bootstrapUrl, null);
		getPagePanel().setListener(this);
		mountPoint.add(getCoordinatedView());

		Window.addWindowResizeListener(this);
		History.addHistoryListener(this);
		if (!("".equals(bootstrapUrl) || bootstrapUrl == null)) {
			if (bootstrapUrl.startsWith(HistoryUtils.HASH_TOK))
				bootstrapUrl = bootstrapUrl.substring(1);
			isUrlBootstrapped = false;
			DeferredCommand.add(new Command() {
				public void execute() {
					onHistoryChanged(bootstrapUrl);
					isUrlBootstrapped = true;
				}
			});
		}
	}
	
	public String getBootstrapUrl() {
		return bootstrapUrl;
	}
	
	public boolean isUrlBootstrapped() {
		return isUrlBootstrapped;
	}
	
	public void setUrlBootstrapped(boolean val) {
		isUrlBootstrapped = val;
	}
	
	public void registerPageController(Widget view, AbstractPageController ctrl) {
		pageControllerMap.put(view, ctrl);
		pageNameControllerMap.put(ctrl.getPageName(), ctrl);
		controllers.add(ctrl);
	}
	
	public void unregisterPageController(Widget view) {
		AbstractPageController ctrl = (AbstractPageController) pageControllerMap.remove(view);
		pageNameControllerMap.remove(ctrl);
		controllers.remove(ctrl);
	}
	
	public AbstractPageController getPageController(String pageName) {
		return (AbstractPageController) pageNameControllerMap.get(pageName);
	}

	// PagePanel.Listener
	public void onLeavePage(int idx, Widget from, Widget to) {
		AbstractPageController ctrl = (AbstractPageController) pageControllerMap.get(from);
		ctrl.onLeavePage(idx, from, to);
	}
	
	public boolean onBeforePageSelected(int idx, Widget target) {
		AbstractPageController ctrl = (AbstractPageController) pageControllerMap.get(target);
		return ctrl.onBeforePageSelected(idx, target);
	}

	public void onPageSelected(int idx, Widget target) {
		AbstractPageController ctrl = (AbstractPageController) pageControllerMap.get(target);
		ctrl.onPageSelected(idx, target);
	}

	// WindowResizeListener
	public void onWindowResized(int w, int h) {
		for (Iterator iter = controllers.iterator(); iter.hasNext();) {
			AbstractPageController ctrl = (AbstractPageController) iter.next();
			ctrl.onContainerResized(w, h);
		}
	}

	// HistoryListener 
	public void onHistoryChanged(String historyToken) {
		if (Gem.stone.isDebugEnabled())
			Gem.stone.log(this, "onHistoryChanged: " + historyToken, null);
		if (historyToken == null)
			return;
		HashMap queryMap = new HashMap();
		historyToken = HistoryUtils.parseToken(historyToken, queryMap);
		AbstractPageController ctrl = (AbstractPageController) pageNameControllerMap.get(historyToken);
		ctrl.onHistoryChange(historyToken, queryMap);
	}
}
